package com.cxl.live.websocket.server;

import com.alibaba.fastjson.JSON;
import com.cxl.live.websocket.model.Message;
import com.cxl.live.websocket.util.WebSocketUtil;
import lombok.Synchronized;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.CrossOrigin;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

/**
 * @Description: RoomWebSocketServer 房间号的websocket通信
 * @Author: ChenXueLi
 * @Date: 2019-01-30 13:11
 * 你是一段成熟的代码，要学会自己改bug
 */
@Slf4j
@ServerEndpoint(value = "/room/{roomUrl}")
@CrossOrigin
@Component
public class RoomWebSocketServer {

    /**
     * 当前在线的情况 String 房间号， HashSet<Session> 房间中的用户session
     */
    private static Map<String, HashSet<Session>> online = new HashMap<>();

    /**
     * 所有连接数
     */
    private static int onlineCount = 0;

    /**
     * 连接建立成功调用的方法（进入房间）
     * @param session 会话
     * @param roomUrl 房间号
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("roomUrl") String roomUrl) {
        // 去获取当前的room存不存在

        // 判断房间状态

        // 判断缓存中是否存在该房间
        if(!online.containsKey(roomUrl)) {
            online.put(roomUrl, new HashSet<>());
        };
        // 将session存入
        online.get(roomUrl).add(session);

        log.info("有用户进入房间：" + roomUrl);
        log.info("当前房间在线人数为： " + online.get(roomUrl).size());
        // 在线数加1（所有的sessionId）
        addOnlineCount();
    }

    /**
     * 连接关闭调用的方法（离开房间）
     * @param session 会话
     * @param roomUrl 房间号
     */
    @OnClose
    public void onClose(Session session, @PathParam("roomUrl") String roomUrl) {
        // 获取房间中的人数信息
        online.get(roomUrl).remove(session);
        log.info("有用户离开房间：" + roomUrl);
        log.info("当前房间在线人数为： " + online.get(roomUrl).size());
        // 在线数减1（所有的sessionId）
        subOnlineCount();
    }

    /**
     * 收到客户端消息后调用的方法
     * @param content 客户端发送过来的消息
     * @param session
     * @param roomUrl
     */
    @OnMessage
    public void onMessage(String content, Session session, @PathParam("roomUrl") String roomUrl) {
        // json字符串转对象
        Message message = JSON.parseObject(content, Message.class);
        message.setRoomUrl(roomUrl);
        // 处理数据
        WebSocketUtil.getInstance().handleAction(session, message);

//        log.info("来自客户端的消息:" + content);
    }

    /**
     * 错误
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("发生错误");
        error.printStackTrace();
    }

    /**
     * 获取在线人数
     * @return
     */
    @Synchronized
    public static int getOnlineCount() {
        return onlineCount;
    }

    /**
     * 在线人数加1
     */
    @Synchronized
    private static void addOnlineCount() {
        onlineCount++;
    }

    /**
     * 在线人数减1
     */
    @Synchronized
    private static void subOnlineCount() {
        onlineCount--;
    }

    /**
     * 根据房间地址获取房间内的用户的session列表
     * @param roomURL
     * @return
     */
    public static HashSet<Session> getSessionListByRoom(String roomURL) {
        return online.get(roomURL);
    }

}
